package com.xof.phonecall.telecom

import android.content.Context
import android.content.Intent
import android.net.Uri
import android.provider.ContactsContract
import android.telecom.Call
import android.telecom.TelecomManager
import android.telecom.VideoProfile
import android.telephony.SubscriptionManager
import android.util.Patterns
import android.widget.Toast

object MyCallManager {

    var sCall: Call? = null
    private var sIsAutoCalling = false
    private var sAutoCallingContactsList: List<ContactsContract.Contacts>? = null
    private var sAutoCallPosition = 0
    private val mSubscriptionManager: SubscriptionManager? = null
    private var mPermissionList: Array<String>? = null

    var mPhoneNumber: String = ""


    /**
     * Call a given number
     *
     * @param context
     * @param number
     */
    fun call(context: Context, number: String) {
        try {
            //如果当前正在拨号，则退出
//            if (mPhoneNumber.isNotBlank()) {
//                return
//            }
            // Create call intent
            TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE
            mPhoneNumber = number
            val callIntent = Intent(Intent.ACTION_CALL, Uri.parse("tel: " + Uri.encode(number)))

            // Handle sim card selection
            val simCard: Int = 0//2//getSimSelection(context)
            val dualSimTypes = arrayOf(
                "extra_asus_dial_use_dualsim",
                "com.android.phone.extra.slot",  //基本上是这个
                "slot",
                "simslot",
                "sim_slot",
                "subscription",  //华为是这个
                "Subscription",
                "phone",
                "com.android.phone.DialingMode",
                "simSlot",
                "slot_id",  //小米是这个
                "simId",
                "simnum",
                "phone_type",
                "slotId",
                "slotIdx"
            )
            dualSimTypes.forEach { item ->
                callIntent.putExtra(item, simCard);
            }

            // Start the call
            context.startActivity(callIntent)

        } catch (e: SecurityException) {
            Toast.makeText(
                context,
                "Couldn't make a call due to security reasons",
                Toast.LENGTH_LONG
            ).show()
        } catch (e: NullPointerException) {
            Toast.makeText(context, "Couldnt make a call, no phone number", Toast.LENGTH_LONG)
                .show()
        }
    }

    /**
     * Get sim selection from preferences
     *
     * @param context
     * @return number of selected sim
     */
    fun getSimSelection(context: Context?): Int {
        return try {
            // try getting the sim selection preference
//            PreferenceUtils.getInstance(context).getInt(R.string.pref_sim_select_key)
            1
        } catch (e: java.lang.NullPointerException) {
            Toast.makeText(context, "Couldn't get sim selection", Toast.LENGTH_LONG).show()
            -1
        }
    }

    /**
     * Answers incoming call
     */
    fun answer() {
        if (sCall != null) {
            sCall!!.answer(VideoProfile.STATE_AUDIO_ONLY)
        }
    }

    /**
     * Ends call
     * If call ended from the other side, disconnects
     *
     * @return true whether there's no more calls awaiting
     */
    fun reject() {
        if (sCall != null) {
            if (sCall!!.state == Call.STATE_RINGING) {
                sCall!!.reject(false, null)
            } else {
                sCall!!.disconnect()
            }
            if (sIsAutoCalling) sAutoCallPosition++
        }
    }

    /**
     * Put call on hold
     *
     * @param hold
     */
    fun hold(hold: Boolean) {
        if (sCall != null) {
            if (hold) sCall!!.hold() else sCall!!.unhold()
        }
    }

    /**
     * Open keypad
     *
     * @param c
     */
    fun keypad(c: Char) {
        if (sCall != null) {
            sCall!!.playDtmfTone(c)
            sCall!!.stopDtmfTone()
        }
    }

    /**
     * Add a call to the current call
     *
     * @param call
     */
    fun addCall(call: Call?) {
        if (sCall != null) {
            sCall!!.conference(call)
        }
    }

    /**
     * Registers a Callback object to the current call
     *
     * @param callback the callback to register
     */
    fun registerCallback(callback: Call.Callback) {
        if (sCall == null) {
            println("注册回调失败")
            return
        }
        sCall!!.registerCallback(callback)
    }

    /**
     * Unregisters the Callback from the current call
     *
     * @param callback the callback to unregister
     */
    fun unregisterCallback(callback: Call.Callback?) {
        if (sCall == null) return
        sCall!!.unregisterCallback(callback)
    }

    // -- Auto-Calling -- //

    // -- Auto-Calling -- //
    /**
     * Start the auto calling on the list of contacts
     *
     * @param list          a list of contacts
     * @param context       the context
     * @param startPosition the start position from which to start calling
     */
//    fun startAutoCalling(list: List<Contact?>, context: AppCompatActivity, startPosition: Int) {
//        sIsAutoCalling = true
//        sAutoCallPosition = startPosition
//        sAutoCallingContactsList = list
//        if (sAutoCallingContactsList.isEmpty()) Timber.e("No contacts in auto calling list")
//        nextCall(context)
//    }

    /**
     * Go to the next call
     *
     * @param context
     */
    fun nextCall(context: Context) {
        if (sAutoCallingContactsList != null && sAutoCallPosition < sAutoCallingContactsList!!.size) {
            val phoneNumber: String = "13113043327"
            if (validatePhoneNumber(phoneNumber)) {
                call(context, phoneNumber)
            } else {
                Toast.makeText(context, "Can't call $phoneNumber", Toast.LENGTH_SHORT).show()
                sAutoCallPosition++
                nextCall(context)
            }
        } else {
            finishAutoCall()
        }
    }

    /**
     * Finish the loop
     */
    fun finishAutoCall() {
        sIsAutoCalling = false
        sAutoCallPosition = 0
    }

    /**
     * Check wither is currently auto calling
     *
     * @return
     */
    fun isAutoCalling(): Boolean {
        return sIsAutoCalling
    }

    // -- Getters -- //

    // -- Getters -- //
    /**
     * Gets the phone number of the contact from the end side of the current call
     * in the case of a voicemail number, returns "Voicemail"
     *
     * @return String - phone number, or voicemail. if not recognized, return null.
     */
//    fun getDisplayContact(context: Context?): ContactsContract.Contacts? {
//        val number: String
//        // try getting the number of the other side of the call
//        number = try {
//            URLDecoder.decode(sCall!!.details.handle.toString(), "utf-8").replace("tel:", "")
//        } catch (e: java.lang.Exception) {
//            return ContactUtils.UNKNOWN
//        }
//        // check if number is a voice mail
//        if (number.contains("voicemail")) return ContactUtils.VOICEMAIL
//        // get the contact
//        val contact: ContactsContract.Contacts = ContactUtils.getContactByPhoneNumber(
//            context,
//            number
//        ) // get the contacts with the number
//        return if (contact == null) ContactsContract(number, number, null) // return a number contact
//        else contact // contact is valid, return it
//    }

    /**
     * Returnes the current state of the call from the Call object (named sCall)
     *
     * @return Call.State
     */
    fun getState(): Int {
        return if (sCall == null) Call.STATE_DISCONNECTED else sCall!!.state // if no call, return disconnected
    }

    /**
     * Validates the given String as a phone number
     *
     * @param phoneNumber
     * @return boolean
     */
    fun validatePhoneNumber(phoneNumber: String?): Boolean {
        return Patterns.PHONE.matcher(phoneNumber).matches()
    }
}